package com.fansl.koala.quickdev.module.users.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fansl.koala.quickdev.common.bean.PageBean;
import com.fansl.koala.quickdev.common.constants.CommonConstants;
import com.fansl.koala.quickdev.common.enums.*;
import com.fansl.koala.quickdev.module.users.bean.dto.SysUserDTO;
import com.fansl.koala.quickdev.module.users.entity.SysUser;
import com.fansl.koala.quickdev.module.users.entity.SysUserRole;
import com.fansl.koala.quickdev.module.users.mapper.SysUserMapper;
import com.fansl.koala.quickdev.module.users.service.ISysUserService;
import com.fansl.koala.quickdev.module.users.vo.SysUserVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author fansl
 * @since 2020-03-13
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {
    @Resource
    private SysUserRoleServiceImpl sysUserRoleService;

    /**
     * 根据用户名获取用户信息
     *
     * @param username 用户名
     * @return 用户信息
     */
    @Override
    public SysUser getByUsername(String username) {
        if (StrUtil.isBlank(username)) {
            return null;
        }
        return getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, username)
                .eq(SysUser::getDelFlag, DeleteFlagEnum.NOT_DELETE.getCode()));
    }

    /**
     * 账号激活
     *
     * @param id 用户id
     * @return TRUE/FALSE
     */
    @Override
    public Boolean accountActivate(Long id) {
        SysUser sysUser = new SysUser();
        sysUser.setId(id);
        sysUser.setActivateFlag(ActivateFlagEnum.ACTIVATED.getCode());
        return updateById(sysUser);
    }

    /**
     * 根据邮箱获取用户信息
     *
     * @param email 邮箱
     * @return 用户信息
     */
    @Override
    public SysUser getByEmail(String email) {
        if (StrUtil.isBlank(email)) {
            return null;
        }
        return getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getEmail, email)
                .eq(SysUser::getDelFlag, DeleteFlagEnum.NOT_DELETE.getCode()));
    }

    /**
     * 更新用户信息
     *
     * @param param 更新参数
     * @return TRUE/FALSE
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateById(SysUserDTO param) {
        //更新角色信息
        sysUserRoleService.remove(Wrappers.<SysUserRole>lambdaQuery().eq(SysUserRole::getUserId, param.getId()));
        List<SysUserRole> sysUserRoleList = param.getRoleIds().stream().map(roleId -> {
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setRoleId(roleId);
            sysUserRole.setUserId(param.getId());
            return sysUserRole;
        }).collect(Collectors.toList());
        if (!sysUserRoleList.isEmpty()) {
            sysUserRoleService.saveBatch(sysUserRoleList);
        }
        //更新用户信息
        SysUser sysUser = new SysUser();
        sysUser.setId(param.getId());
        sysUser.setNickname(param.getNickname());
        sysUser.setGender(param.getGender().getCode());
        sysUser.setDeptId(param.getDeptId());
        return baseMapper.updateById(sysUser) > 0;
    }

    /**
     * 分页查询数据
     *
     * @param page    分页条件
     * @param sysUser 查询参数
     * @return 分页数据
     */
    @Override
    public PageBean<SysUserVo> listPage(PageBean<SysUserVo> page, SysUser sysUser) {
        //分页参数
        Page<SysUser> queryPage = new Page<>();
        queryPage.setCurrent(page.getPageNo())
                .setSize(page.getPageSize());
        if (StrUtil.isNotBlank(page.getSortOrder()) && StrUtil.isNotBlank(page.getSortField())) {
            OrderItem orderItem = new OrderItem();
            orderItem.setAsc(page.getSortOrder().equals(CommonConstants.PAGE_QUERY_ORDER_ASC));
            orderItem.setColumn(StrUtil.toUnderlineCase(page.getSortField()));
            queryPage.setOrders(Collections.singletonList(orderItem));
        }
        //查询条件
        SysUser queryParam = new SysUser();
        if(StrUtil.isNotBlank(sysUser.getUsername())){
            queryParam.setUsername(sysUser.getUsername());
        }
        LambdaQueryWrapper<SysUser> queryWrapper = Wrappers.lambdaQuery(queryParam);

        Page<SysUser> result = this.page(queryPage, queryWrapper);
        //结果转vo
        List<SysUserVo> data = sysUser2Vo(result.getRecords());
        //转换结果
        page.setData(data);
        page.setTotalCount(result.getTotal());
        page.setTotalPage(result.getPages());
        return page;
    }

    /**
     * 对象转换
     *
     * @param sysUsers 源对象
     * @return 目标对象
     */
    private List<SysUserVo> sysUser2Vo(List<SysUser> sysUsers) {
        //获取用户的角色信息
        List<Long> userIds = sysUsers.stream().map(SysUser::getId)
                .collect(Collectors.toList());
        if(userIds.isEmpty()){
            return Collections.emptyList();
        }
        List<SysUserRole> sysUserRoles =
                sysUserRoleService.list(Wrappers.<SysUserRole>lambdaQuery().in(SysUserRole::getUserId, userIds));
        Map<Long, List<SysUserRole>> userRoleMap = sysUserRoles.stream()
                .collect(Collectors.groupingBy(SysUserRole::getUserId));
        List<SysUserVo> sysUserVos = sysUsers.stream().map(sysUser -> {
            SysUserVo target = new SysUserVo();
            BeanUtil.copyProperties(sysUser, target,
                    CopyOptions.create().setIgnoreError(true));
            target.setGender(GenderEnum.findByCode(sysUser.getGender()));
            //账户已激活并且账户未上锁，状态为正常，否则为禁用
            if (sysUser.getActivateFlag().equals(ActivateFlagEnum.ACTIVATED.getCode())
                    && sysUser.getLockFlag().equals(LockFlagEnum.UNLOCK.getCode())) {
                target.setStatus(StatusEnum.NORMAL);
            } else {
                target.setStatus(StatusEnum.DISABLE);
            }
            List<SysUserRole> userRoles = userRoleMap.getOrDefault(sysUser.getId(), Collections.emptyList());
            target.setRoles(userRoles.stream().map(SysUserRole::getRoleId).collect(Collectors.toList()));
            return target;
        }).collect(Collectors.toList());

        return sysUserVos;
    }

    /**
     * 对象转换
     *
     * @param sysUser 源对象
     * @return 目标对象
     */
    private SysUserVo sysUser2Vo(SysUser sysUser) {
        SysUserVo target = new SysUserVo();
        BeanUtil.copyProperties(sysUser, target,
                CopyOptions.create().setIgnoreError(true));
        target.setGender(GenderEnum.findByCode(sysUser.getGender()));
        //账户已激活并且账户未上锁，状态为正常，否则为禁用
        if (sysUser.getActivateFlag().equals(ActivateFlagEnum.ACTIVATED.getCode())
                && sysUser.getLockFlag().equals(LockFlagEnum.UNLOCK.getCode())) {
            target.setStatus(StatusEnum.NORMAL);
        } else {
            target.setStatus(StatusEnum.DISABLE);
        }
        List<SysUserRole> sysUserRoles =
                sysUserRoleService.list(Wrappers.<SysUserRole>lambdaQuery().eq(SysUserRole::getUserId, sysUser.getId()));
        target.setRoles(sysUserRoles.stream().map(SysUserRole::getRoleId).collect(Collectors.toList()));
        return target;
    }
}
